package com.yy.exception;

import com.yy.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: lyy
 * Date: 2021/12/14 16:33
 */
@Slf4j
@RestControllerAdvice
public class GlobalException {

	private static String SYSTEM_ERROR = "系统异常";
	private static String PARAM_ERROR = "参数异常";

	/**
	 * 请求参数异常 start
	 */

	@ExceptionHandler(HttpMessageNotReadableException.class)
	public String httpMessageNotReadableException(HttpMessageNotReadableException e){
		log.error(e.getMessage(), e);
		return PARAM_ERROR;
	}

	@ExceptionHandler(MethodArgumentNotValidException.class)
	public String methodArgumentNotValidException(MethodArgumentNotValidException e){
		log.error(e.getMessage(), e);
		BindingResult bindingResult = e.getBindingResult();
		if(bindingResult.hasErrors()){
			List<ObjectError> allErrors = bindingResult.getAllErrors();
			String error = allErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(","));
			return error;
		}
		return PARAM_ERROR;
	}

	@ExceptionHandler(MissingPathVariableException.class)
	public String missingPathVariableException(MissingPathVariableException e){
		log.error(e.getMessage(), e);
		return PARAM_ERROR;
	}

	@ExceptionHandler(MethodArgumentTypeMismatchException.class)
	public String methodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e){
		log.error(e.getMessage(), e);
		return PARAM_ERROR;
	}

	@ExceptionHandler(ConstraintViolationException.class)
	public String constraintViolationException(ConstraintViolationException e){
		log.error(e.getMessage(), e);
		Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
		String error = constraintViolations.stream().map(ConstraintViolation::getMessageTemplate).collect(Collectors.joining(","));
		return error;
	}

	@ExceptionHandler(BindException.class)
	public String bindException(BindException e){
		log.error(e.getMessage(), e);
		BindingResult bindingResult = e.getBindingResult();
		if(bindingResult.hasErrors()){
			List<ObjectError> allErrors = bindingResult.getAllErrors();
			String error = allErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(","));
			return error;
		}
		return PARAM_ERROR;
	}
	/**
	 * 请求参数异常 end
	 */



	@ExceptionHandler(Exception.class)
	public String exceptionHandler(Exception e){
		log.error("全局异常：【{}】",e.getMessage(), e);
		return SYSTEM_ERROR;
	}

}